<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Introduction - Zend Framework Manual</title>

    <link href="../css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="../css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <link href="../css/styles.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Zend Framework</h1>
<h2>Programmer's Reference Guide</h2>
<ul>
    <li><a href="../en/zend.infocard.basics.html">Inglês (English)</a></li>
    <li><a href="../pt-br/zend.infocard.basics.html">Português Brasileiro (Brazilian Portuguese)</a></li>
</ul>
<table width="100%">
    <tr valign="top">
        <td width="85%">
            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.infocard.html">Zend_InfoCard</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.infocard.html">Zend_InfoCard</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.json.html">Zend_Json</a></div>
                    </td>
                </tr>
            </table>
<hr />
<div id="zend.infocard.basics" class="section"><div class="info"><h1 class="title">Introduction</h1></div>
    

    <p class="para">
        The <span class="classname">Zend_InfoCard</span> component implements relying-party
        support for Information Cards. Information Cards are used for identity
        management on the internet and authentication of users to web sites. The web sites
        that the user ultimately authenticates to are called <em class="emphasis">relying-parties</em>.
    </p>

    <p class="para">
        Detailed information about information cards and their importance to the
        internet identity metasystem can be found on the <a href="http://www.identityblog.com/" class="link external">&raquo; IdentityBlog</a>.
    </p>

    <div class="section" id="zend.infocard.basics.theory"><div class="info"><h1 class="title">Basic Theory of Usage</h1></div>
        

        <p class="para">
            Usage of <span class="classname">Zend_InfoCard</span> can be done one of two ways:
            either as part of the larger <span class="classname">Zend_Auth</span> component via
            the <span class="classname">Zend_InfoCard</span> authentication adapter or as a
            stand-alone component. In both cases an information card can be
            requested from a user by using the following <acronym class="acronym">HTML</acronym> block in your
            <acronym class="acronym">HTML</acronym> login form:
        </p>

        <pre class="programlisting brush: html">
&lt;form action=&quot;http://example.com/server&quot; method=&quot;POST&quot;&gt;
  &lt;input type=&#039;image&#039; src=&#039;/images/ic.png&#039; align=&#039;center&#039;
        width=&#039;120px&#039; style=&#039;cursor:pointer&#039; /&gt;
  &lt;object type=&quot;application/x-informationCard&quot;
          name=&quot;xmlToken&quot;&gt;
   &lt;param name=&quot;tokenType&quot;
         value=&quot;urn:oasis:names:tc:SAML:1.0:assertion&quot; /&gt;
   &lt;param name=&quot;requiredClaims&quot;
         value=&quot;http://.../claims/privatepersonalidentifier
         http://.../claims/givenname
         http://.../claims/surname&quot; /&gt;
 &lt;/object&gt;
&lt;/form&gt;
</pre>


        <p class="para">
            In the example above, the <span class="property">requiredClaims</span>
            &lt;param&gt; tag is used to identify pieces of information known as claims (i.e.
            person&#039;s first name, last name) which the web site (a.k.a &quot;relying party&quot;) needs in
            order a user to authenticate using an information card. For your reference, the full
            <acronym class="acronym">URI</acronym> (for instance the <em class="emphasis">givenname</em> claim) is as
            follows:
            <var class="filename">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname</var>
        </p>

        <p class="para">
            When the above <acronym class="acronym">HTML</acronym> is activated by a user (clicks on it), the
            browser will bring up a card selection program which not only shows
            them which information cards meet the requirements of the site, but
            also allows them to select which information card to use if multiple
            meet the criteria. This information card is transmitted as an <acronym class="acronym">XML</acronym>
            document to the specified POST <acronym class="acronym">URL</acronym> and is ready to be
            processed by the <span class="classname">Zend_InfoCard</span> component.
        </p>

        <p class="para">
            Note, Information cards can only be <acronym class="acronym">HTTP</acronym> <acronym class="acronym">POST</acronym>ed to
            <acronym class="acronym">SSL</acronym>-encrypted <acronym class="acronym">URL</acronym>s. Please consult your web
            server&#039;s documentation on how to set up <acronym class="acronym">SSL</acronym> encryption.
        </p>
    </div>

    <div class="section" id="zend.infocard.basics.auth"><div class="info"><h1 class="title">Using as part of Zend_Auth</h1></div>
        

        <p class="para">
            In order to use the component as part of the <span class="classname">Zend_Auth</span>
            authentication system, you must use the provided
            <span class="classname">Zend_Auth_Adapter_InfoCard</span> to do so (not available in
            the standalone <span class="classname">Zend_InfoCard</span> distribution). An example
            of its usage is shown below:
        </p>

        <pre class="programlisting brush: php">
&lt;?php
if (isset($_POST[&#039;xmlToken&#039;])) {

    $adapter = new Zend_Auth_Adapter_InfoCard($_POST[&#039;xmlToken&#039;]);

    $adapter-&gt;addCertificatePair(&#039;/usr/local/Zend/apache2/conf/server.key&#039;,
                                 &#039;/usr/local/Zend/apache2/conf/server.crt&#039;);

    $auth = Zend_Auth::getInstance();

    $result = $auth-&gt;authenticate($adapter);

    switch ($result-&gt;getCode()) {
        case Zend_Auth_Result::SUCCESS:
            $claims = $result-&gt;getIdentity();
            print &quot;Given Name: {$claims-&gt;givenname}&lt;br /&gt;&quot;;
            print &quot;Surname: {$claims-&gt;surname}&lt;br /&gt;&quot;;
            print &quot;Email Address: {$claims-&gt;emailaddress}&lt;br /&gt;&quot;;
            print &quot;PPI: {$claims-&gt;getCardID()}&lt;br /&gt;&quot;;
            break;
        case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
            print &quot;The Credential you provided did not pass validation&quot;;
            break;
        default:
        case Zend_Auth_Result::FAILURE:
            print &quot;There was an error processing your credentials.&quot;;
            break;
    }

    if (count($result-&gt;getMessages()) &gt; 0) {
        print &quot;&lt;pre&gt;&quot;;
        var_dump($result-&gt;getMessages());
        print &quot;&lt;/pre&gt;&quot;;
    }

}
?&gt;
&lt;hr /&gt;
&lt;div id=&quot;login&quot; style=&quot;font-family: arial; font-size: 2em;&quot;&gt;
&lt;p&gt;Simple Login Demo&lt;/p&gt;
 &lt;form method=&quot;post&quot;&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Login&quot; /&gt;
   &lt;object type=&quot;application/x-informationCard&quot; name=&quot;xmlToken&quot;&gt;
    &lt;param name=&quot;tokenType&quot;
          value=&quot;urn:oasis:names:tc:SAML:1.0:assertion&quot; /&gt;
    &lt;param name=&quot;requiredClaims&quot;
          value=&quot;http://.../claims/givenname
                 http://.../claims/surname
                 http://.../claims/emailaddress
                 http://.../claims/privatepersonalidentifier&quot; /&gt;
  &lt;/object&gt;
 &lt;/form&gt;
&lt;/div&gt;
</pre>


        <p class="para">
            In the example above, we first create an instance of the
            <span class="classname">Zend_Auth_Adapter_InfoCard</span> and pass the <acronym class="acronym">XML</acronym>
            data posted by the card selector into it. Once an instance has been created you
            must then provide at least one <acronym class="acronym">SSL</acronym> certificate public/private key
            pair used by the web server that received the <acronym class="acronym">HTTP</acronym>
            <acronym class="acronym">POST</acronym>. These files are used to validate the destination of the
            information posted to the server and are a requirement when using Information Cards.
        </p>

        <p class="para">
            Once the adapter has been configured, you can then use the standard
            <span class="classname">Zend_Auth</span> facilities to validate the provided
            information card token and authenticate the user by examining the
            identity provided by the  <span class="methodname">getIdentity()</span> method.
        </p>
    </div>

    <div class="section" id="zend.infocard.basics.standalone"><div class="info"><h1 class="title">Using the Zend_InfoCard component standalone</h1></div>
        

        <p class="para">
            It is also possible to use the <span class="classname">Zend_InfoCard</span> component as a
            standalone component by interacting with the
            <span class="classname">Zend_InfoCard</span> class directly. Using the
            <span class="classname">Zend_InfoCard</span> class is very similar to its use with the
            <span class="classname">Zend_Auth</span> component. An example of its use is shown below:
        </p>

        <pre class="programlisting brush: php">
&lt;?php
if (isset($_POST[&#039;xmlToken&#039;])) {
    $infocard = new Zend_InfoCard();
    $infocard-&gt;addCertificatePair(&#039;/usr/local/Zend/apache2/conf/server.key&#039;,
                                  &#039;/usr/local/Zend/apache2/conf/server.crt&#039;);

    $claims = $infocard-&gt;process($_POST[&#039;xmlToken&#039;]);

    if($claims-&gt;isValid()) {
        print &quot;Given Name: {$claims-&gt;givenname}&lt;br /&gt;&quot;;
        print &quot;Surname: {$claims-&gt;surname}&lt;br /&gt;&quot;;
        print &quot;Email Address: {$claims-&gt;emailaddress}&lt;br /&gt;&quot;;
        print &quot;PPI: {$claims-&gt;getCardID()}&lt;br /&gt;&quot;;
    } else {
        print &quot;Error Validating identity: {$claims-&gt;getErrorMsg()}&quot;;
    }
}
?&gt;
&lt;hr /&gt;
&lt;div id=&quot;login&quot; style=&quot;font-family: arial; font-size: 2em;&quot;&gt;
 &lt;p&gt;Simple Login Demo&lt;/p&gt;
 &lt;form method=&quot;post&quot;&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Login&quot; /&gt;
   &lt;object type=&quot;application/x-informationCard&quot; name=&quot;xmlToken&quot;&gt;
    &lt;param name=&quot;tokenType&quot;
          value=&quot;urn:oasis:names:tc:SAML:1.0:assertion&quot; /&gt;
    &lt;param name=&quot;requiredClaims&quot;
          value=&quot;http://.../claims/givenname
                 http://.../claims/surname
                 http://.../claims/emailaddress
                 http://.../claims/privatepersonalidentifier&quot; /&gt;
   &lt;/object&gt;
 &lt;/form&gt;
&lt;/div&gt;
</pre>


        <p class="para">
            In the example above, we use the <span class="classname">Zend_InfoCard</span> component
            independently to validate the token provided by the user. As was the
            case with the <span class="classname">Zend_Auth_Adapter_InfoCard</span>, we create an
            instance of <span class="classname">Zend_InfoCard</span> and then set one or more
            <acronym class="acronym">SSL</acronym> certificate public/private key pairs used by the web server. Once
            configured, we can use the  <span class="methodname">process()</span> method to process
            the information card and return the results.
        </p>
    </div>

    <div class="section" id="zend.infocard.basics.claims"><div class="info"><h1 class="title">Working with a Claims object</h1></div>
        

        <p class="para">
            Regardless of whether the <span class="classname">Zend_InfoCard</span> component is used as
            a standalone component or as part of <span class="classname">Zend_Auth</span> via
            <span class="classname">Zend_Auth_Adapter_InfoCard</span>, the ultimate
            result of the processing of an information card is a
            <span class="classname">Zend_InfoCard_Claims</span> object. This object contains the
            assertions (a.k.a. claims) made by the submitting user based on the
            data requested by your web site when the user authenticated. As
            shown in the examples above, the validity of the information card
            can be ascertained by calling the
             <span class="methodname">Zend_InfoCard_Claims::isValid()</span> method. Claims
            themselves can either be retrieved by simply accessing the
            identifier desired (i.e. <span class="property">givenname</span>) as a property of
            the object or through the  <span class="methodname">getClaim()</span> method.
        </p>

        <p class="para">
            In most cases you will never need to use the  <span class="methodname">getClaim()</span>
            method. However, if your <span class="property">requiredClaims</span> mandate that
            you request claims from multiple different sources/namespaces then
            you will need to extract them explicitly using this method (simply
            pass it the full <acronym class="acronym">URI</acronym> of the claim to retrieve its value from within
            the information card). Generally speaking however, the
            <span class="classname">Zend_InfoCard</span> component will set the default
            <acronym class="acronym">URI</acronym> for claims to be the one used the most frequently within the
            information card itself and the simplified property-access method can be used.
        </p>

        <p class="para">
            As part of the validation process, it is the developer&#039;s responsibility to
            examine the issuing source of the claims contained within the
            information card and to decide if that source is a trusted source of
            information. To do so, the  <span class="methodname">getIssuer()</span> method is
            provided within the <span class="classname">Zend_InfoCard_Claims</span> object which
            returns the <acronym class="acronym">URI</acronym> of the issuer of the information card claims.
        </p>
    </div>

    <div class="section" id="zend.infocard.basics.attaching"><div class="info"><h1 class="title">Attaching Information Cards to existing accounts</h1></div>
        

        <p class="para">
            It is possible to add support for information cards to an existing
            authentication system by storing the private personal identifier
            (PPI) to a previously traditionally-authenticated account and
            including at least the
            <var class="filename">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier</var>
            claim as part of the <span class="property">requiredClaims</span> of the request. If
            this claim is requested then the <span class="classname">Zend_InfoCard_Claims</span>
            object will provide a unique identifier for the specific card that
            was submitted by calling the  <span class="methodname">getCardID()</span> method.
        </p>

        <p class="para">
            An example of how to attach an information card to an existing
            traditional-authentication account is shown below:
        </p>

        <pre class="programlisting brush: php">
// ...
public function submitinfocardAction()
{
    if (!isset($_REQUEST[&#039;xmlToken&#039;])) {
        throw new ZBlog_Exception(&#039;Expected an encrypted token &#039; .
                                  &#039;but was not provided&#039;);
    }

    $infoCard = new Zend_InfoCard();
    $infoCard-&gt;addCertificatePair(SSL_CERTIFICATE_PRIVATE,
                                  SSL_CERTIFICATE_PUB);

    try {
        $claims = $infoCard-&gt;process($request[&#039;xmlToken&#039;]);
    } catch(Zend_InfoCard_Exception $e) {
        // TODO Error processing your request
        throw $e;
    }

    if ($claims-&gt;isValid()) {
        $db = ZBlog_Data::getAdapter();

        $ppi = $db-&gt;quote($claims-&gt;getCardID());
        $fullname = $db-&gt;quote(&quot;{$claims-&gt;givenname} {$claims-&gt;surname}&quot;);

        $query = &quot;UPDATE blogusers
                     SET ppi = $ppi,
                         real_name = $fullname
                   WHERE username=&#039;administrator&#039;&quot;;

        try {
            $db-&gt;query($query);
        } catch(Exception $e) {
            // TODO Failed to store in DB
        }

        $this-&gt;view-&gt;render();
        return;
    } else {
        throw new
            ZBlog_Exception(&quot;Infomation card failed security checks&quot;);
    }
}
</pre>

    </div>

    <div class="section" id="zend.infocard.basics.adapters"><div class="info"><h1 class="title">Creating Zend_InfoCard Adapters</h1></div>
        

        <p class="para">
            The <span class="classname">Zend_InfoCard</span> component was designed to allow for
            growth in the information card standard through the use of a modular
            architecture. At this time, many of these hooks are unused and can be
            ignored, but there is one class that should be written for
            any serious information card implementation: the
            <span class="classname">Zend_InfoCard</span> adapter.
        </p>

        <p class="para">
            The <span class="classname">Zend_InfoCard</span> adapter is used as a callback
            mechanism within the component to perform various tasks, such as
            storing and retrieving Assertion IDs for information cards when they
            are processed by the component. While storing the assertion IDs of
            submitted information cards is not necessary, failing to do so opens
            up the possibility of the authentication scheme being compromised
            through a replay attack.
        </p>

        <p class="para">
            To prevent this, one must implement the
            <span class="classname">Zend_InfoCard_Adapter_Interface</span> and set an
            instance of this interface prior to calling either the
             <span class="methodname">process()</span> (standalone) or
             <span class="methodname">authenticate()</span> method as a <span class="classname">Zend_Auth</span>
            adapter. To set this interface, the  <span class="methodname">setAdapter()</span> method should
            be used. In the example below, we set a <span class="classname">Zend_InfoCard</span> adapter and
            use it in our application:
        </p>

        <pre class="programlisting brush: php">
class myAdapter implements Zend_InfoCard_Adapter_Interface
{
    public function storeAssertion($assertionURI,
                                   $assertionID,
                                   $conditions)
    {
        /* Store the assertion and its conditions by ID and URI */
    }

    public function retrieveAssertion($assertionURI, $assertionID)
    {
        /* Retrieve the assertion by URI and ID */
    }

    public function removeAssertion($assertionURI, $assertionID)
    {
        /* Delete a given assertion by URI/ID */
    }
}

$adapter  = new myAdapter();

$infoCard = new Zend_InfoCard();
$infoCard-&gt;addCertificatePair(SSL_PRIVATE, SSL_PUB);
$infoCard-&gt;setAdapter($adapter);

$claims = $infoCard-&gt;process($_POST[&#039;xmlToken&#039;]);
</pre>

    </div>
</div>
        <hr />

            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.infocard.html">Zend_InfoCard</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.infocard.html">Zend_InfoCard</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.json.html">Zend_Json</a></div>
                    </td>
                </tr>
            </table>
</td>
        <td style="font-size: smaller;" width="15%"> <style type="text/css">
#leftbar {
	float: left;
	width: 186px;
	padding: 5px;
	font-size: smaller;
}
ul.toc {
	margin: 0px 5px 5px 5px;
	padding: 0px;
}
ul.toc li {
	font-size: 85%;
	margin: 1px 0 1px 1px;
	padding: 1px 0 1px 11px;
	list-style-type: none;
	background-repeat: no-repeat;
	background-position: center left;
}
ul.toc li.header {
	font-size: 115%;
	padding: 5px 0px 5px 11px;
	border-bottom: 1px solid #cccccc;
	margin-bottom: 5px;
}
ul.toc li.active {
	font-weight: bold;
}
ul.toc li a {
	text-decoration: none;
}
ul.toc li a:hover {
	text-decoration: underline;
}
</style>
 <ul class="toc">
  <li class="header home"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="reference.html">Zend Framework Reference</a></li>
  <li class="header up"><a href="zend.infocard.html">Zend_InfoCard</a></li>
  <li class="active"><a href="zend.infocard.basics.html">Introduction</a></li>
 </ul>
 </td>
    </tr>
</table>

<script type="text/javascript" src="../js/shCore.js"></script>
<script type="text/javascript" src="../js/shAutoloader.js"></script>
<script type="text/javascript" src="../js/main.js"></script>

</body>
</html>